﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using drinking.Managers;
using drinking.Models;
using drinking.Helpers;

namespace drinking.Api.WX
{
    [Route("api/wx/order")]
    [ApiController]
    public class OrderController : ControllerBase
    {
        /// <summary>
        /// 创建订单，并返回支付参数
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public ApiResult Add(Order order)
        {
            Customer customer = UserManager.CurrCustomer.Value;
            // 1.门店 、设备是否正常
            int storeIndexInCache = StoreManager.GetStoresIndex4Id(order.StoreId);
            if (storeIndexInCache == -1)
            {
                throw new Exception_(ResultCode.NO_OK, "门店不存在");
            }
            Store store = StoreManager.CacheStores[storeIndexInCache];
            if (store.StoreStatus != 0 || store.BusinessStatus != 0)
            {
                throw new Exception_(ResultCode.NO_OK, "门店未营业");
            }
            if(order.ItemSize != order.OrderItems.Count || order.ItemSize < 1)
            {
                //数量不对
                throw new Exception_(ResultCode.NO_OK, "数量不对");
            }

            order.CustomerId = customer.CustomerId;
            order.CreateTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
            order.PayTime = "";
            order.StoreId = store.StoreId;
            order.StoreName = store.StoreName;
            order.CompleteTime = "";


            order.OrderStatus = 0;
            //1.5 插入数据库
            var db = new DBContext().Db;
            try
            {
                db.BeginTran();
                //创建OrderCode
                order.OrderCode = store.CreateOrderCode();
                order.OrderId = db.Insertable(order).ExecuteReturnIdentity();
                decimal sumPrice = 0;
                foreach (var item in order.OrderItems)
                {
                    item.OrderId = order.OrderId;
                    // 验证饮品、辅料库存,价格
                    var (canPay, errMsg) = store.DrinkCheck(item);
                    if (!canPay)
                    {
                        throw new Exception_(ResultCode.NO_OK, errMsg);
                    }
                    sumPrice += item.Price;
                    item.OrderItemCode = store.CreateOrderItemCode();
                    item.OrderItemId = db.Insertable(item).ExecuteReturnIdentity();
                }

                // 核验总价
                if(sumPrice != order.Amount)
                {
                    throw new Exception_(ResultCode.NO_OK, "价格错误");
                }

                var (outTradeNo, prepayId) = WxPayManager.CreatePayTransaction(order);

                order.OutTradeNo = outTradeNo;
                db.Updateable(order).UpdateColumns(o => new { o.OutTradeNo });
                var dict = WxPayManager.CreatePayParams(prepayId);
                // 事务提交
                db.CommitTran();
                //3 创建预支付申请
                return ApiResult.Success(dict);
            }
            catch (Exception ex)
            {
                // 事务回滚
                db.RollbackTran();
                return ApiResult.Fail(ex.Message);
            }
           
            
        }


        /// <summary>
        /// 重新发起支付
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <returns></returns>
        [HttpPost("repay")]
        public ApiResult Repay(int orderId)
        {
            Customer customer = UserManager.CurrCustomer.Value;
            var db = new DBContext().Db;
            Order order = db.Queryable<Order>().InSingle(orderId);
            if (order == null || order.OrderStatus != 0 || order.CustomerId != customer.CustomerId)
            {
                throw new Exception_(ResultCode.NO_OK, "订单丢失了。。。");
            }
            order.OrderItems = db.Queryable<OrderItem>().Where(item => item.OrderId == orderId).ToList();

            // 1.门店 、设备是否正常
            int storeIndexInCache = StoreManager.GetStoresIndex4Id(order.StoreId);
            if (storeIndexInCache == -1)
            {
                throw new Exception_(ResultCode.NO_OK, "门店不存在");
            }
            Store store = StoreManager.CacheStores[storeIndexInCache];
            if (store.StoreStatus != 0 || store.BusinessStatus != 0)
            {
                throw new Exception_(ResultCode.NO_OK, "门店未营业");
            }
            foreach (var item in order.OrderItems)
            {
                // 验证饮品、辅料库存
                var (canPay, errMsg) = store.DrinkCheck(item);
                if (!canPay)
                {
                    throw new Exception_(ResultCode.NO_OK, errMsg);
                }
            }

           // string openid = WxManager.GetUserOpenCode(openidCode);
            var (outTradeNo, prepayId) = WxPayManager.CreatePayTransaction(order);
            order.OutTradeNo = outTradeNo;
            new DBContext().Db.Updateable(order).UpdateColumns(o => new { o.OutTradeNo });
            var dict = WxPayManager.CreatePayParams(prepayId);
            return ApiResult.Success(dict);
        }


        /// <summary>
        /// 支付结果通知,该接口由微信支付平台调用
        /// </summary>
        /// <param name="jsonBody"></param>
        /// <returns></returns>
        [HttpPost("payCallBack")]
        public ApiResult PayCallBack([FromBody] string jsonBody)
        {
            // string callbackJson = HttpContext.Request.Body.Re
            string timestamp = HttpContext.Request.Headers["Wechatpay-Timestamp"];
            string nonce = HttpContext.Request.Headers["Wechatpay-Nonce"];
            string signature = HttpContext.Request.Headers["Wechatpay-Signature"];
            string serialNumber = HttpContext.Request.Headers["Wechatpay-Serial"];
            WxPayManager.PayCallBack(jsonBody, timestamp, nonce, signature, serialNumber);
            return ApiResult.Success();
        }


        /// <summary>
        /// 分业查询个人的订单
        /// </summary>
        /// <param name="pageNum">第几页</param>
        /// <param name="pageSize">每页个数</param>
        /// <param name="orderId">订单状态id</param>
        /// <param name="orderStatus">订单状态 40:调制中  50：已完成</param>
        /// <returns></returns>
        [HttpGet("listPage")]
        public ApiResult GetOrderListPage(int pageNum, int pageSize, int? orderId, int? orderStatus)
        {
            Customer customer = UserManager.CurrCustomer.Value;
            var db = new DBContext().Db;
            int count = 0;
            var query = db.Queryable<Order>()
                .Where(order => order.CustomerId == customer.CustomerId);
            if (orderId != null)
            {
                query.Where(order => order.OrderId == orderId);
            }
            if (orderStatus != null)
            {
                query.Where(order => order.OrderStatus == orderStatus);
            }

             var list = query.OrderBy(order => order.OrderId)
                .ToPageList(pageNum, pageSize, ref count).ToList();
            foreach (var order in list)
            {
                order.OrderItems = db.Queryable<OrderItem>().Where(item => item.OrderId == order.OrderId).ToList();
            }
            return ApiResult.Success(new
            {
                Count = count,
                PageNum = pageNum,
                List = list
            });
        }


        /// <summary>
        /// 不分页查询个人的订单
        /// </summary>
        /// <param name="orderId">订单状态id</param>
        /// <param name="orderStatus">订单状态 40:调制中  50：已完成</param>
        /// <returns></returns>
        [HttpGet("list")]
        public ApiResult GetOrderList(int? orderId, int? orderStatus)
        {
            Customer customer = UserManager.CurrCustomer.Value;
            var db = new DBContext().Db;
            var query = db.Queryable<Order>()
                .Where(order => order.CustomerId == customer.CustomerId);
            if (orderId != null)
            {
                query.Where(order => order.OrderId == orderId);
            }
            if (orderStatus != null)
            {
                query.Where(order => order.OrderStatus == orderStatus);
            }

            var list = query.OrderBy(order => order.OrderId).ToList();
            foreach (var order in list)
            {
                order.OrderItems = db.Queryable<OrderItem>().Where(item => item.OrderId == order.OrderId).ToList();
            }
            return ApiResult.Success(list);
        }



        /// <summary>
        /// 查询订单的等待数量
        /// </summary>
        /// <param name="storeId">门店id</param>
        /// <param name="orderId">订单id</param>
        /// <returns></returns>
        [HttpGet("waitingData")]
        public ApiResult WaitingData(int storeId, int orderId)
        {
            var db = new DBContext().Db;
            return ApiResult.Success(new 
            {
                OrderCount = db.Queryable<Order>().Count(order => order.StoreId == storeId && (order.OrderStatus > 10 || order.OrderStatus <= 40) && order.OrderId < orderId),
                OrderItemsCount = db.Queryable<Order>().Where(order => order.StoreId == storeId && (order.OrderStatus > 10 || order.OrderStatus <= 40) && order.OrderId < orderId).Sum(order => order.ItemSize),
            });
        }


        /// <summary>
        /// 查询订单的支付结果
        /// </summary>
        /// <param name="orderId">订单id</param>
        /// <returns></returns>
        [HttpGet("queryPayResult")]
        public ApiResult QueryPayResult(int orderId)
        {
            Customer customer = UserManager.CurrCustomer.Value;
            var db = new DBContext().Db;
            Order order = db.Queryable<Order>().Where(o => o.OrderId == orderId && o.CustomerId == customer.CustomerId).First();
            if (order != null)
            {
                if (order.OrderStatus == 0)
                {
                    if (WxPayManager.QueryPayResult(order.OutTradeNo))
                    {
                        order.OrderStatus = 10;
                        order.PayTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
                        if (!db.Updateable(order).Where(o => o.OrderId == orderId && o.OrderStatus == 0).UpdateColumns(o => new { o.OrderStatus, o.PayTime }).ExecuteCommandHasChange())
                        {
                            order = db.Queryable<Order>().InSingle(orderId);
                        }

                    }
                }
                return ApiResult.Success(order);
            }
            else
            {
                return ApiResult.Fail("订单查询失败");
            }
            
            
        }


    }
}
